package com.wait.onlinepicture.aop;

import com.wait.onlinepicture.annotation.CommentAuthCheck;
import com.wait.onlinepicture.exception.BusinessException;
import com.wait.onlinepicture.exception.ErrorCode;
import com.wait.onlinepicture.model.entity.PictureComment;
import com.wait.onlinepicture.model.entity.User;
import com.wait.onlinepicture.model.enums.UserRoleEnum;
import com.wait.onlinepicture.service.CommentService;
import com.wait.onlinepicture.service.UserService;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;

/**
 * 评论权限校验 AOP
 *
 * @author with葡萄成熟时
 */
@Aspect
@Component
public class CommentAuthInterceptor {

    @Resource
    private UserService userService;
    
    @Resource
    private CommentService commentService;

    /**
     * 执行拦截
     *
     * @param joinPoint 切入点
     * @param commentAuthCheck 评论权限校验注解
     */
    @Around("@annotation(commentAuthCheck)")
    public Object doInterceptor(ProceedingJoinPoint joinPoint, CommentAuthCheck commentAuthCheck) throws Throwable {
        String mustRole = commentAuthCheck.mustRole();
        boolean mustCreator = commentAuthCheck.mustCreator();
        
        RequestAttributes requestAttributes = RequestContextHolder.currentRequestAttributes();
        HttpServletRequest request = ((ServletRequestAttributes) requestAttributes).getRequest();
        
        // 当前登录用户
        User loginUser = userService.getLoginUser(request);
        
        // 角色权限校验
        if (mustRole != null && !mustRole.isEmpty()) {
            UserRoleEnum mustRoleEnum = UserRoleEnum.getEnumByValue(mustRole);
            if (mustRoleEnum != null) {
                UserRoleEnum userRoleEnum = UserRoleEnum.getEnumByValue(loginUser.getUserRole());
                if (userRoleEnum == null) {
                    throw new BusinessException(ErrorCode.NO_AUTH_ERROR);
                }
                if (UserRoleEnum.ADMIN.equals(mustRoleEnum) && !UserRoleEnum.ADMIN.equals(userRoleEnum)) {
                    throw new BusinessException(ErrorCode.NO_AUTH_ERROR);
                }
            }
        }
        
        // 创建者权限校验
        if (mustCreator) {
            // 获取评论ID参数
            MethodSignature signature = (MethodSignature) joinPoint.getSignature();
            Method method = signature.getMethod();
            Object[] args = joinPoint.getArgs();
            Long commentId = null;
            
            // 从方法参数中获取评论ID
            for (int i = 0; i < args.length; i++) {
                if (args[i] instanceof Long) {
                    commentId = (Long) args[i];
                    break;
                } else if (args[i] != null && args[i].getClass().getName().contains("Request")) {
                    // 尝试从请求对象中获取id字段
                    try {
                        java.lang.reflect.Field field = args[i].getClass().getDeclaredField("id");
                        field.setAccessible(true);
                        commentId = (Long) field.get(args[i]);
                        break;
                    } catch (Exception e) {
                        // 字段不存在，继续查找
                    }
                }
            }
            
            if (commentId != null) {
                PictureComment comment = commentService.getById(commentId);
                if (comment == null) {
                    throw new BusinessException(ErrorCode.NOT_FOUND_ERROR, "评论不存在");
                }
                
                // 如果不是管理员，且不是评论创建者，则无权限
                UserRoleEnum userRoleEnum = UserRoleEnum.getEnumByValue(loginUser.getUserRole());
                if (!UserRoleEnum.ADMIN.equals(userRoleEnum) && !comment.getUserId().equals(loginUser.getId())) {
                    throw new BusinessException(ErrorCode.NO_AUTH_ERROR);
                }
            }
        }
        
        // 通过权限校验，放行
        return joinPoint.proceed();
    }
}